#coding=utf-8
#LightCam 日志监控程序
#init by hfh 20150212

import multiprocessing,subprocess,threading
import socket,os,time,re,traceback,sys
import lc_libs

def func(this):
	
	agent_hostname=this['agent_hostname']
	filename=this['filename']
	keyword=this['keyword']
	interval=this['interval']
	severity=this['severity']
	schedule=this['schedule']
	holiday=this['holiday']
	
	Node=agent_hostname
	AlertGroup="OraAlertLogErr"
	AlertKey=filename
	
	flagfile=lchome+'/flag/logfile_ora__'+filename.replace('/','_')
	
	fr=open(filename,'rb')
	try:
		fc=open(flagfile,'r+')
	except IOError:
		fr.readlines()
		pointer=fr.tell()
		#print pointer
		fc=open(flagfile,'w')
		fc.write(str(pointer))
		fc.close()
		fc=open(flagfile,'r+')
	
	pointer=int(fc.read())
	nsize=os.path.getsize(filename)
	if nsize < pointer:
		print "file rebuild"
		pointer=0
	
	fr.seek(pointer,0)

	buf=fr.read()
	if len(buf)==0:
		return 0

	for filecontent in buf.split('\n'):
		time.sleep(0.01)
		if "LightCam" in filecontent:
			continue
		if str(filecontent) == "":
			continue
		flagkey=0
		for i in keywords:
			if i in filecontent:
				flagkey=1
				break
		
		if flagkey==0:
			if re.match(keyword,filecontent):
				AlertKey=filename
				Severity=severity
				Type="1"
				#Summary=filecontent
				Summary=agent_hostname+"日志"+filename+"出现错误信息:"+filecontent
				strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				print strs
				db.update_eventsdb_rt(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				#logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
				#logfile.write(logdate+" "+strs+"\n")
				#logfile.flush()
			#else:
				#Severity="1"
				#Type="2"
				#Summary=filecontent
				#Summary=agent_hostname+"日志"+filename+"出现正常信息:"+filecontent
				#strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				#print strs
				#db.update_eventsdb(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				#logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
				#logfile.write(logdate+" "+strs+"\n")
				#logfile.flush()

	pointer=fr.tell()

	fc.seek(0,0)
	fc.truncate()
	fc.write(str(pointer))

	fc.close()
	fr.close()
	
if __name__ == "__main__":

	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	os.system("mv %s %s.%s" % (logfilename,logfilename,today))
	
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()
	
	agent_hostname=lc_libs.lc_gethostname()
	
	#初始化events数据库
	#dbfile="../db/lc_events.db"
	#tablename="lc_events"
	#tablefield="Node varchar(32),AlertGroup varchar(64),AlertKey varchar(64),Severity varchar(8),Type varchar(8),LastOccurrence varchar(32),Summary varchar(256)"
	#db=lc_libs.lc_dboperater(dbfile,tablename,tablefield)
	#db.create_db()
	#db.close_db()

	try:
		#初始化数据库
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		events_dbname='lc_events'
		events_tablename='lc_events'
		
		history_dbname='lc_history'
		history_tablename="lc_logfile"
		
		events_db=db.useDatabase(events_dbname)
		events_table=db.UseCollection(events_db,events_tablename)
		
		history_db=db.useDatabase(history_dbname)
		history_table=db.UseCollection(history_db,history_tablename)

	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)


	MonitorList = []
	
	for lines in open(confname):
		#if line[0] == '#' or agent_hostname != line.split("\t")[0]:
		if lines[0] == '#' or lines.split("\t")[0] not in (agent_hostname,'default'):
			continue

		line=lines.strip('\r\n').split('\t')
		dconf={}
		
		dconf['agent_hostname']=line[0]
		dconf['filename']=line[1]
		dconf['keyword']=line[2]
		dconf['interval']=int(line[3])
		dconf['severity']=line[4]
		dconf['schedule']=line[5]
		dconf['holiday']=line[6]

		flagfile=lchome+'/flag/logfile_ora__'+dconf['filename'].replace('/','_')
		os.system("rm -f "+flagfile)
		
		MonitorList.append(dconf)

	keywords=[
						"alter database backup controlfile to",
						"ALTER SYSTEM SET service_names",
						"Completed" ,
						"ALTER SYSTEM ARCHIVE LOG",
						"ORA-3136",
						"service_",
						"TNS-12505",
						" 12505",
						"TNS-12514",
						" 12514",
						"TNS-12525",
						" 12525",
						"TNS-12535",
						" 12535",
						"TNS-12606",
						" 12606",
						"TNS-12502",
						" 12502",
						"TNS-12506",
						" 12506",
						"TNS-12521",
						" 12521",
						"FAL archive failed. Archiver continuing",
						"Archival Error. Archiver continuing",
						"FAL archive failed, see trace file",
						"Tns error struct",
						"See Note 411.1 at My Oracle Support for error packaging details",
						"Errors in file ",
						"Fatal NI connect error 12170"
						]


	usedtime=0
	
	while True:
		time.sleep(1)
		realtime=int(time.time())
		
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		holiday_state = lc_libs.lc_isholiday()
		
		threads = []
		for i in MonitorList:
			if int(i['holiday']) == 1 and holiday_state == True:
				continue
				
			time_state = lc_libs.lc_schedule(i['schedule'])
			if time_state == False:
				continue
			
			flag=realtime%int(i['interval'])
			#print flag
			if flag<=usedtime:
				#print i
				t = threading.Thread(target=func,args=(i,))
				threads.append(t)
		
		for t in threads:
			t.start()
			while True:
				#print len(threading.enumerate())
				time.sleep(0.01)
				if(len(threading.enumerate()) < 100):
					break

		#排除执行程序导致的时间差
		usedtime=int(time.time())-realtime
		#print "usedtime:%s" % usedtime
